package com.lu.stack.common.model.response;

import cn.hutool.core.util.StrUtil;
import lombok.*;

import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class R<T> implements Serializable {

  /** 错误码 */
  private Integer code;

  private String message;

  private T data;

  private Map<String, Object> params = null;

  public R(Integer code, String message) {
    this.code = code;
    this.message = message;
  }

  public static <T> R<T> success(T t) {
    R<T> r = new R<>();
    r.setCode(0);
    r.setMessage("");
    r.setData(t);
    return r;
  }

  public static <T> R<T> success() {
    return success(null);
  }

  public static <T> R<T> failed(String msg, Object... args) {
    R<T> r = new R<>();
    r.setCode(Code.OP_FAIL.getCode());
    r.setMessage(StrUtil.format(msg, args));
    return r;
  }

  public static <T> R<T> failed(Integer code, String msg, Object... args) {
    R<T> r = new R<>();
    r.setCode(code);
    r.setMessage(StrUtil.format(msg, args));
    return r;
  }

  public static <T> R<T> failed(){
    return R(null, Code.OP_FAIL.getCode(), null);
  }

  public static <T> R<T> failed(Code Code){
    return R(null, Code.getCode(), Code.getDescription());
  }

  private static <T> R<T> R(T data, Integer code, String msg) {
    R<T> R = new R<>();
    R.setCode(code);
    R.setData(data);
    R.setMessage(msg);
    return R;
  }

  public R<T> code(Integer code) {
    this.code = code;
    return this;
  }

  public R<T> msg(String msg, Object... args) {
    this.message = StrUtil.format(msg, args);
    return this;
  }

  public R<T> data(T data) {
    this.data = data;
    return this;
  }

  public R<T> params(Map<String, Object> params){
    this.params = params;
    return this;
  }

  public R<T> params(String k, Object v){
    if(this.params == null){
      this.params = new LinkedHashMap<>();
    }
    this.params.put(k, v);
    return this;
  }

  public boolean isFailed(){
    return this.code == null || this.code < 0;
  }

  public boolean isSuccess(){
    return this.code != null && this.code >= 0;
  }

  @Getter
  @AllArgsConstructor
  public enum Code {

    /***************************************正确码***************************************/

    OP_SUCCESS(0, "操作成功"),
    HANDLE_SUCCESS(1, "处理成功"),
    SEND_SUCCESS(2, "发送成功"),
    UPLOAD_SUCCESS(3, "上传成功"),
    ACCEPTED(4, "受理的"),
    NOT_ACCEPTED(5, "未受理的"),


    /***************************************错误码***************************************/

    /**
     * 常规错误
     */
    OP_FAIL(-1, "操作失败"),
    SERVER_failed(-10002, "服务器异常"),
    SYSTEM_BUSY(-10003, "系统繁忙,请稍候再试"),
    GATEWAY_NOT_FOUND_SERVICE(-10004, "服务未找到"),
    GATEWAY_failed(-10005, "网关异常"),
    SERVICE_LIMIT_FLOW(-10006, "服务限流"),
    SERVICE_DEGRADATION(-10006, "服务降级"),
    ARGUMENT_NOT_VALID(-10007, "请求参数校验不通过"),
    SESSION_TIMEOUT(-10008, "会话超时"),
    PARAM_ILLEGAL(-10009, "参数不合法"),
    PARAM_REQUIRED(-100010, "必填项缺失"),
    UPLOAD_FILE_FAILED(-100011, "文件上传失败"),

    /**
     * 账户、验证码问题
     */
    FAIL_LOGIN(-30001, "登陆失败"),
    FAIL_LOGOUT(-30002, "登出失败"),
    VERIFICATION_CODE_failed(-30003, "验证码错误"),
    VERIFICATION_CODE_EXPIRE(-30004, "验证码过期"),
    NOT_LOGIN(-30005, "用户未登录"),
    USER_ALREADY_REG(-30006, "用户已注册"),
    ACCOUNT_NOT_EXISTED(-30007, "账号不存在"),
    ACCOUNT_FREEZED(-30008, "您的账号已禁用，请联系管理员"),
    PWD_failed(-30009, "密码错误"),

    /**
     * 文件问题
     */
    UPLOAD_FAIL(-40001, "上传失败"),
    FILE_CONTENT_ILLEGAL(-40002, "文件内容不合法"),
    FILE_TYPE_NOT_SUPPORT(-40003, "文件类型不支持"),
    FILE_SIZE_TOO_BIG(-40004, "文件过大"),
    FILE_SIZE_TOO_SMALL(-40005, "文件过小"),
    MATERIAL_SURPLUS_ALARM(-40006, "素材文件剩余数量告警"),
    MATERIAL_EXCESS_QUANTITY(-40007, "素材文件数量超额"),
    FILE_NOT_EXISTED(-40008, "文件不存在"),

    /**x
     * 消息问题
     */
    SEND_FAIL(-50001, "发送失败"),
    HANDLE_FAIL(-50002, "处理失败"),
    SEND_PARAMS_failed(-50003, "消息发送参数异常"),

    /**
     * 任务
     */
    TASK_VERIFY_FAIL(-60001, "任务校验失败"),
    TASK_DECOMPOSE_FAIL(-60002, "任务分解失败"),

    /**
     * 基础模块
     */
    TASK_NOT_FIND(-70001, "任务信息没有找到"),

    ;

    private final Integer code;
    private final String description;
  }

}
